﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace NConf.Interfaces
{
    public interface IConfigSource
    {
        //---------------------------------------------------------------------

        #region Properties

        /// <summary>
        /// A property, presenting a dictionary representing the configuration elements provided by this config source.
        /// </summary>
        Dictionary<string, object> Configuration { get; set; }

        #endregion

        //---------------------------------------------------------------------

        #region Get/Set Values

        /// <summary>
        /// Gets the value specified by config path, or throws an exception.
        /// </summary>
        /// <param name="configPath">A string represented the 'dotted' path to the configuration element desired.</param>
        /// <returns>The object specified by the config path.</returns>
        object GetValue(string configPath);

        /// <summary>
        /// Gets the value specified by the config path, or returns the default value.
        /// </summary>
        /// <param name="configPath">A string represented the 'dotted' path to the configuration element desired.</param>
        /// <param name="defaultValue">The object to return if the desired object isn't found.</param>
        /// <returns>The object specified by the config path, or the default value.</returns>
        object GetValue(string configPath, object defaultValue);

        /// <summary>
        /// Sets the given value specified by a key value pair.
        /// </summary>
        /// <param name="kvp">A key value pair of config path, and value.</param>
        void SetValue(KeyValuePair<string, object> kvp);
        
        /// <summary>
        /// Sets the config element specified by the path to the given value.
        /// </summary>
        /// <param name="configPath">The path to the element to set.</param>
        /// <param name="value">The value to set the element to.</param>
        void SetValue(string configPath, object value);

        #endregion

        //---------------------------------------------------------------------

        #region Test Elements

        /// <summary>
        /// Checks to see if the path specified has a value (including null), or is unset (or a dictionary).
        /// </summary>
        /// <remarks>
        /// This function returns true if a specific configuration value is set in the config. If the path specifies a
        /// dictionary or is unset, this function returns false.
        /// </remarks>
        /// <param name="configPath">The path to the configuration element we're testing.</param>
        /// <returns>Returns true if set, false otherwise.</returns>
        bool HasValue(string configPath);

        /// <summary>
        /// Checks to see if the path specified contains other values (i.e. is a config section.)
        /// </summary>
        /// <param name="configPath">The path to the configuration element we're testing.</param>
        /// <returns>Returns true if the path has sub elements, false otherwise.</returns>
        bool IsSection(string configPath);

        #endregion

        //---------------------------------------------------------------------

        #region ConfigKey Generation

        /// <summary>
        /// Generates a new ConfigKey from the given config path.
        /// </summary>
        /// <param name="configPath">The path to generate the ConfigKey for.</param>
        /// <returns>A new ConfigKey instance.</returns>
        dynamic GetConfigKey(string configPath);

        #endregion

        //---------------------------------------------------------------------
    } // end IConfigSource
} // end NConf.Interfaces
